Skip to content

Fix split-screen UI wrong positioning on window resize#989

Merged
codeHusky merged 2 commits intosmartcmd:mainfrom
MrTheShy:fix-ui-wrong-resize
Mar 9, 2026
Merged

Fix split-screen UI wrong positioning on window resize#989
codeHusky merged 2 commits intosmartcmd:mainfrom
MrTheShy:fix-ui-wrong-resize

Conversation

@MrTheShy
Copy link
Contributor

@MrTheShy MrTheShy commented Mar 9, 2026

Description

Fix split-screen HUD, Chat, and Tooltips rendering incorrectly when the Windows64 game window is below 1080p.

Changes

Previous Behavior

In 2-player vertical split (SPLIT_LEFT/RIGHT) at window heights below 1080, HUD elements (crosshair, hotbar, hearts, player name) shifted downward, and Chat/Tooltips drifted in the wrong direction. The issue worsened as the window got smaller — at 720p the HUD was noticeably off-center, and at very small windows elements could move entirely off-screen. Horizontal split and quadrant modes were not affected.

Root Cause

Two separate bugs, both originating from 4J's assumption that these platforms always run at 1080p:

1. ComputeTileScale clamp (HUD, Chat, Tooltips)

ComputeTileScale computes scale = max(scaleW, scaleH) then clamps it to >= 1.0 to prevent the SWF from being rendered too small in quadrant mode. In vertical split, tileHeight = screenH. On consoles this equals the movie height (1080), so scaleH = 1.0 and the clamp has no effect. On PC at sub-1080 heights (e.g. 900), scaleH = 900/1080 = 0.833 gets clamped to 1.0, leaving the SWF at native 1920x1080 and cropping the bottom. repositionHud then passes visibleH = 900 to ActionScript, which sees less than the full height and shifts elements downward to "center" them.

2. ComputeSplitContentOffset (Chat, Tooltips)

Chat and Tooltips applied a position offset from ComputeSplitContentOffset to the tile origin. This function returned (0,0) at the design resolution (1920x1080) but computed incorrect offsets at any other size — Player 1 tooltips drifted left/right in vertical split and up/down in horizontal split. Player 2 was unaffected because the function only applied offsets to LEFT/TOP viewports.

New Behavior

Split-screen HUD, Chat, and Tooltips render correctly at any window resolution on Windows64. At 1080p and above the rendering is unchanged. Below 1080p the overlays scale down to fit the full SWF height, keeping all elements in their designed positions.

Fix Implementation

HUD (UIScene_HUD::render): After ComputeTileScale, added a vertical-split override that allows the scale to go below 1.0 when the window height is less than the movie height. This scales the SWF down to fit the full height, so repositionHud passes visibleH = movieHeight to ActionScript and no vertical repositioning occurs. The clamp is still active for horizontal split and quadrant mode where it is needed.

Chat (UIComponent_Chat::render) / Tooltips (UIComponent_Tooltips::render): Removed the ComputeSplitContentOffset call entirely — the SWF content is already positioned correctly by the tile crop, so no additional offset is needed. Applied the same vertical-split scale-down fix as the HUD.

Related Issues

  • Fixes [https://discord.com/channels/1478227187843858563/1480314590637326499]

In vertical split at window heights below 1080, ComputeTileScale's min-scale clamp (>= 1.0) prevented the SWF from scaling down to fit, cropping the bottom and causing repositionHud to shift HUD elements downward. Chat and Tooltips additionally applied an offset from ComputeSplitContentOffset that only produced correct values at the 1920x1080 design resolution.

Override the scale for vertical split so the SWF fits the full window height when it is shorter than the movie. Remove the broken content offset from Chat and Tooltips -- the tile crop already positions the content correctly.
@MrTheShy
Copy link
Contributor Author

MrTheShy commented Mar 9, 2026

@codeHusky i am also fixing gamma so wait a second

The gamma shader sampled the full backbuffer texture (UV 0..1) into each player's viewport, stretching the entire screen into every split region. Extended the shader constant buffer with per-viewport UV offset and scale so each pass samples only its own portion of the backbuffer.

ComputeViewportForPlayer was hardcoded to top/bottom for 2 players, ignoring the vertical split setting. Rewrote it to read each player's m_iScreenSection directly, which already accounts for the split orientation preference.

Secondary players have no Graphics menu and cannot change gamma. CachePlayerGammas now reads the primary player's setting and applies it uniformly to all viewports.
@codeHusky codeHusky merged commit e2adaa0 into smartcmd:main Mar 9, 2026
1 check passed
piebotc pushed a commit to piebotc/LegacyEvolved that referenced this pull request Mar 9, 2026
* Fix split-screen UI wrong positioning on window resize

In vertical split at window heights below 1080, ComputeTileScale's min-scale clamp (>= 1.0) prevented the SWF from scaling down to fit, cropping the bottom and causing repositionHud to shift HUD elements downward. Chat and Tooltips additionally applied an offset from ComputeSplitContentOffset that only produced correct values at the 1920x1080 design resolution.

Override the scale for vertical split so the SWF fits the full window height when it is shorter than the movie. Remove the broken content offset from Chat and Tooltips -- the tile crop already positions the content correctly.

* Fix gamma post-process in split-screen

The gamma shader sampled the full backbuffer texture (UV 0..1) into each player's viewport, stretching the entire screen into every split region. Extended the shader constant buffer with per-viewport UV offset and scale so each pass samples only its own portion of the backbuffer.

ComputeViewportForPlayer was hardcoded to top/bottom for 2 players, ignoring the vertical split setting. Rewrote it to read each player's m_iScreenSection directly, which already accounts for the split orientation preference.

Secondary players have no Graphics menu and cannot change gamma. CachePlayerGammas now reads the primary player's setting and applies it uniformly to all viewports.
MrTheShy added a commit to MrTheShy/MinecraftConsoles that referenced this pull request Mar 9, 2026
…ain compile error

Merges 19 commits from smartcmd/MinecraftConsoles (upstream/main) into the
dedicated-server branch and resolves the resulting networking conflicts while
preserving all dedicated-server-specific behaviour.

---

Upstream commits included in this merge:

- Port over RCE Patches from LCEMP (smartcmd#1023)
  Hardened packet parsing across ByteArrayInputStream/OutputStream, Tag,
  Socket, Connection, and a dozen packet types; bounds-checked reads, length
  limits, and safe decompression paths to close known RCE vectors.

- Revert accidentally pushed "LCEMP RCE fixes" / LCEMP RCE fixes
  Intermediate clean-up of the above work.

- Reject duplicate UIDs on login and remove noisy gdraw debug log (smartcmd#1013)
  Incoming players whose UID is already active are now disconnected instead
  of force-kicking the existing player.  Removes a per-frame debug printf
  left in gdraw_SetViewSizeAndWorldScale.

- Always show version overlay, add more info
  Version string is now always visible at runtime.

- Fix split-screen UI wrong positioning on window resize (smartcmd#989)
- Reimplement boat gravity again (smartcmd#988)
- Use correctly sized icons on 720p (smartcmd#883)
- Revert workaround for loading HD textures (smartcmd#999)
- Fix crash when launching at 720p or lower resolutions (smartcmd#981)
- Modernize project codebase (smartcmd#906): NULL → nullptr, C-style cast → C++ cast,
  shared_ptr(new …) → make_shared, misc type fixes.
- Split screen, widescreen support, font rendering and UI scaling fixes (smartcmd#767)
- Flame not working with one-shot arrow (smartcmd#856)
- Fix focus sound playing repeatedly on mouse hover (smartcmd#890)
- Fix stale held item appearing when switching worlds (smartcmd#910)
- Fix F3 debug crash when throwing ender pearl long distance (smartcmd#934)
- Allow closing some menus with inventory/crafting keys (smartcmd#868)
- Fix second-person nametag pitch (smartcmd#963)

---

Conflict resolutions (4 files):

Minecraft.Client/Common/Network/GameNetworkManager.cpp
  Conflict 1 — variable declarations in StartNetworkGame:
    Kept HEAD.  The dedicated-server branch declares `dedicatedNoLocalHostPlayer`
    here and reads it from NetworkGameInitData.  Upstream had dropped that
    variable while modernising the NULL → nullptr style; keeping it is required
    for the dedicated-server startup path.
  Conflict 2 — primary-player connection block:
    Kept HEAD.  When `dedicatedNoLocalHostPlayer` is true the branch
    intentionally skips creating a local-host ClientConnection and goes
    straight to setting the game mode.  Upstream's refactor created a
    ClientConnection with a null socket even for the dedicated path and ran
    the full tick loop; that approach is incompatible with headless operation.

Minecraft.Client/PendingConnection.cpp
  Kept HEAD.  The branch wraps the duplicate-XUID rejection path with a
  #if MINECRAFT_SERVER_BUILD guard that calls
  ServerLogManager::OnRejectedPlayerLogin.  Upstream's version removed that
  call and rewrote only the comment.  Preserving the guard keeps the
  server-build audit log intact.

Minecraft.Client/ServerConnection.cpp
  Kept HEAD comment.  Both sides changed only a single-line comment above
  the playerSnapshot vector.  HEAD's comment ("Disconnect through
  PlayerConnection so clients receive a proper DisconnectPacket before socket
  close") describes the functional intent; it was kept as the more meaningful
  description for this branch.

Minecraft.Client/Windows64/Network/WinsockNetLayer.cpp
  Conflicts 1 & 2 — shutdown thread teardown:
    Hybrid: adopted upstream's nullptr style (consistent with the rest of the
    file after the modernisation PR) while keeping HEAD's more precise comment
    ("Ensure all host-side receive threads have exited before destroying locks").
  Conflict 3 — AcceptThreadProc accept() call:
    Kept HEAD.  HEAD passes sockaddr_in remoteAddress to accept() so that
    TryGetNumericRemoteIp can extract the client IP for connection logging
    and the IP-ban check (ServerRuntime::Access::IsIpBanned).  Upstream had
    simplified the call to accept(…, nullptr, nullptr), which would have
    silently broken IP-based access control in the server build.

---

fix: declare extern ConsoleUIController ui in ServerMain.cpp

Windows64_UIController.h (included by ServerMain.cpp) defines the class but
does not forward-declare the global `ui` instance.  The `extern ConsoleUIController ui`
declaration lives only in Common/UI/UI.h, which is not in ServerMain.cpp's
include chain.  The object is defined in Windows64_UIController.cpp, which IS
compiled as part of Minecraft.Server.vcxproj, so the linker already sees it;
the missing declaration caused a C2065 compile error only in the server
translation unit.  Added the extern declaration alongside the other extern
globals at the top of ServerMain.cpp.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants